home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / mpeg_play-2.1 / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-09  |  19.1 KB  |  780 lines

  1. /*
  2.  * main.c --
  3.  *
  4.  *      Main procedure
  5.  *
  6.  */
  7.  
  8. /*
  9.  * Copyright (c) 1995 The Regents of the University of California.
  10.  * All rights reserved.
  11.  * 
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose, without fee, and without written agreement is
  14.  * hereby granted, provided that the above copyright notice and the following
  15.  * two paragraphs appear in all copies of this software.
  16.  * 
  17.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  18.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  19.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  20.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  21.  * 
  22.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  23.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  24.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  25.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  26.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  27.  */
  28. #include "video.h"
  29. #include "proto.h"
  30. #include <math.h>
  31. #include <sys/types.h>
  32. #include <signal.h>
  33. #include <netinet/in.h>
  34.  
  35. #include "util.h"
  36. #include "dither.h"
  37.  
  38. /* Define buffer length. */
  39.  
  40. #define BUF_LENGTH 80000
  41.  
  42. /* Function return type declarations */
  43. void usage();
  44.  
  45. /* External declaration of main decoding call. */
  46.  
  47. extern VidStream *mpegVidRsrc();
  48. extern VidStream *NewVidStream();
  49.  
  50. /* Declaration of global variable to hold dither info. */
  51.  
  52. int ditherType;
  53. int matched_depth = 8;
  54.  
  55. #ifdef DCPREC
  56. /* Declaration of global variable to hold DC precision */
  57. int dcprec = 0;
  58. #endif
  59.  
  60. /* Global file pointer to incoming data. */
  61. FILE *input;
  62. char *inputName;
  63.  
  64. /* End of File flag. */
  65. int EOF_flag = 0;
  66.  
  67. /* Loop flag. */
  68. int loopFlag = 0;
  69.  
  70. /* Shared memory flag. */
  71. int shmemFlag = 0;
  72.  
  73. /* Quiet flag. */
  74. #ifdef QUIET
  75. int quietFlag = 1;
  76. #else
  77. int quietFlag = 0;
  78. #endif
  79.  
  80. /* Own Color Map flag. */
  81. int owncmFlag = 0;
  82.  
  83. /* "Press return" flag, requires return for each new frame */
  84. int requireKeypressFlag=0;
  85.  
  86. /* Display image on screen? */
  87. int noDisplayFlag = 0;
  88.  
  89. /* Seek Value. 
  90.    0 means do not seek.
  91.    N (N>0) means seek to N after the header is parsed
  92.    N (N<0) means the seek has beeen done to offset N
  93. */
  94. long seekValue = 0;
  95.  
  96. /* Framerate, -1: specified in stream (default)
  97.                0: as fast as possible
  98.                N (N>0): N frames/sec  
  99.                */
  100. int framerate = -1;
  101.  
  102. /* Flags/values to control Arbitrary start/stop frames. */
  103. int partialFlag = 0, startFrame = -1, endFrame = -1;
  104.  
  105. /* Flag for gamma correction */
  106. int gammaCorrectFlag=0;
  107. double gammaCorrect=1.0;
  108.  
  109. /* Setjmp/Longjmp env. */
  110. jmp_buf env;
  111.  
  112. /* Flag for high quality at the expense of speed */
  113. #ifdef QUALITY
  114. int qualityFlag = 1;
  115. #else
  116. int qualityFlag = 0;
  117. #endif
  118.  
  119.  
  120. /*
  121.  *--------------------------------------------------------------
  122.  *
  123.  * int_handler --
  124.  *
  125.  *        Handles Cntl-C interupts..
  126.  *      (two different ones for different OSes)
  127.  *
  128.  * Results:
  129.  *        None.
  130.  *
  131.  * Side effects:
  132.  *        None.
  133.  *
  134.  *--------------------------------------------------------------
  135.  */
  136. #ifndef SIG_ONE_PARAM
  137. void
  138. int_handler()
  139. {
  140.   if (!quietFlag) {
  141.     fprintf(stderr, "Interrupted!\n");
  142.   }
  143.   if (curVidStream != NULL)
  144.     DestroyVidStream(curVidStream);
  145.   exit(1);
  146. }
  147. #else
  148. void
  149. int_handler(signum)
  150. int signum;
  151. {
  152.   if (!quietFlag) {
  153.     fprintf(stderr, "Interrupted!\n");
  154.   }
  155.   if (curVidStream != NULL)
  156.     DestroyVidStream(curVidStream);
  157.   exit(1);
  158. }
  159. #endif
  160.  
  161. /*
  162.  *--------------------------------------------------------------
  163.  *
  164.  * main --
  165.  *
  166.  *        Parses command line, starts decoding and displaying.
  167.  *
  168.  * Results:
  169.  *        None.
  170.  *
  171.  * Side effects:
  172.  *        None.
  173.  *
  174.  *--------------------------------------------------------------
  175.  */
  176.  
  177. void
  178. main(argc, argv)
  179.      int argc;
  180.      char **argv;
  181. {
  182.  
  183.   char *name;
  184.   static VidStream *theStream;
  185.   int mark;
  186.   int i;
  187.  
  188.   mark = 1;
  189.   argc--;
  190.  
  191.   name = (char *) "";
  192.   input = stdin;
  193.   inputName = "stdin";
  194.   ditherType = ORDERED2_DITHER;
  195.   LUM_RANGE = 8;
  196.   CR_RANGE = CB_RANGE = 4;
  197.   noDisplayFlag = 0;
  198.  
  199. #ifdef SH_MEM
  200.   shmemFlag = 1;
  201. #endif
  202.  
  203.   while (argc) {
  204.     if (strcmp(argv[mark], "-nop") == 0) {
  205.       SetPFlag(TRUE);
  206.       SetBFlag(TRUE);
  207.       argc--; mark++;
  208.     } else if (strcmp(argv[mark], "-nob") == 0) {
  209.       SetBFlag(TRUE);
  210.       argc--; mark++;
  211.     } else if (strcmp(argv[mark], "-display") == 0) {
  212.       name = argv[++mark];
  213.       argc -= 2; mark++;
  214.     } else if (strcmp(argv[mark], "-start") == 0) {
  215.       if (argc < 2) usage(argv[0]);
  216.       startFrame = atoi(argv[++mark]);
  217.       if (seekValue != 0) {
  218.         partialFlag = TRUE;
  219.       }
  220.       argc -= 2; mark++;
  221.     } else if (strcmp(argv[mark], "-seek") == 0) {
  222.       if (argc < 2) usage(argv[0]);
  223.       seekValue = atoi(argv[++mark]);
  224.       if (startFrame != -1) startFrame = 0;
  225.       argc -= 2; mark++;
  226.     } else if (strcmp(argv[mark], "-end") == 0) {
  227.       if (argc < 2) usage(argv[0]);
  228.       endFrame = atoi(argv[++mark]);
  229.       partialFlag = TRUE;
  230.       argc -= 2; mark++;
  231.     } else if (strcmp(argv[mark], "-gamma") == 0) {
  232.       if (argc < 2) usage(argv[0]);
  233.       sscanf(argv[++mark], "%lf", &gammaCorrect);
  234.       if (gammaCorrect < 0) {
  235.         fprintf(stderr, "ERROR: Gamma correction must be at least 0.\n");
  236.       }
  237.       if (!quietFlag) {
  238.         printf("Gamma Correction set to %4.2f.\n",gammaCorrect);
  239.       }
  240.  
  241.       gammaCorrectFlag = 1;
  242.       argc -= 2; mark++;
  243. #ifdef DCPREC
  244.     } else if (strcmp(argv[mark], "-dc") == 0) {
  245.       argc--; mark++;
  246.       if (argc < 1) {
  247.         perror("Must specify dc precision after -dc flag");
  248.         usage(argv[0]);
  249.       }
  250.       dcprec = atoi(argv[mark]) - 8;
  251.       if ((dcprec > 3) || (dcprec < 0)) {
  252.         perror("DC precision must be at least 8 and at most 11");
  253.         usage(argv[0]);
  254.       }
  255.       argc--; mark++;
  256. #endif
  257.     } else if (strcmp(argv[mark], "-quality") == 0) {
  258.       argc--; mark++;
  259.       if (argc < 1) {
  260.         perror("Must specify on or off after -quality flag");
  261.         usage(argv[0]);
  262.       }
  263.       if (strcmp(argv[mark], "on") == 0) {
  264.         argc--; mark++;
  265.         qualityFlag = 1;
  266.       }
  267.       else if (strcmp(argv[mark], "off") == 0) {
  268.         argc--; mark++;
  269.         qualityFlag = 0;
  270.       }
  271.       else {
  272.         perror("Must specify on or off after -quality flag");
  273.         usage(argv[0]);
  274.       }
  275.     } else if (strcmp(argv[mark], "-framerate") == 0) {
  276.       argc--; mark++;
  277.       if (argc < 1) {
  278.         perror("Must specify framerate after -framerate flag");
  279.         usage(argv[0]);
  280.       }
  281.       framerate = atoi(argv[mark]);
  282.       argc--; mark++;
  283.     } else if (strcmp(argv[mark], "-dither") == 0) {
  284.       argc--; mark++;
  285.       if (argc < 1) {
  286.         perror("Must specify dither option after -dither flag");
  287.         usage(argv[0]);
  288.       }
  289.       if (strcmp(argv[mark], "hybrid") == 0) {
  290.         argc--; mark++;
  291.         ditherType = HYBRID_DITHER;
  292.       } else if (strcmp(argv[mark], "hybrid2") == 0) {
  293.         argc--; mark++;
  294.         ditherType = HYBRID2_DITHER;
  295.       } else if (strcmp(argv[mark], "fs4") == 0) {
  296.         argc--; mark++;
  297.         ditherType = FS4_DITHER;
  298.       } else if (strcmp(argv[mark], "fs2") == 0) {
  299.         argc--; mark++;
  300.         ditherType = FS2_DITHER;
  301.       } else if (strcmp(argv[mark], "fs2fast") == 0) {
  302.         argc--; mark++;
  303.         ditherType = FS2FAST_DITHER;
  304.       } else if (strcmp(argv[mark], "hybrid2") == 0) {
  305.         argc--; mark++;
  306.         ditherType = HYBRID2_DITHER;
  307.       } else if (strcmp(argv[mark], "2x2") == 0) {
  308.         argc--; mark++;
  309.         ditherType = Twox2_DITHER;
  310.       } else if ((strcmp(argv[mark], "gray256") == 0) ||
  311.                  (strcmp(argv[mark], "grey256") == 0)) {
  312.         argc--; mark++;
  313.         ditherType = GRAY256_DITHER;
  314.       } else if ((strcmp(argv[mark], "gray") == 0) ||
  315.                  (strcmp(argv[mark], "grey") == 0)) {
  316.         argc--; mark++;
  317.         ditherType = GRAY_DITHER;
  318.       } else if ((strcmp(argv[mark], "gray256x2") == 0) ||
  319.                   (strcmp(argv[mark], "grey256x2") == 0)) {
  320.         argc--; mark++;
  321.         ditherType = GRAY2562_DITHER;
  322.       } else if ((strcmp(argv[mark], "gray") == 0) ||
  323.                    (strcmp(argv[mark], "grey") == 0)) {
  324.         argc--; mark++;
  325.         ditherType = GRAY_DITHER;
  326.       } else if ((strcmp(argv[mark], "gray2") == 0) ||
  327.                   (strcmp(argv[mark], "grey2") == 0)) {
  328.         argc--; mark++;
  329.         ditherType = GRAY2_DITHER;
  330.       } else if (strcmp(argv[mark], "color") == 0 ||
  331.                  strcmp(argv[mark], "colour") == 0) {
  332.         argc--; mark++;
  333.         ditherType = FULL_COLOR_DITHER;
  334.       } else if (strcmp(argv[mark], "color2") == 0 ||
  335.                  strcmp(argv[mark], "colour2") == 0) {
  336.         argc--; mark++;
  337.         ditherType = FULL_COLOR2_DITHER;
  338.       } else if (strcmp(argv[mark], "none") == 0) {
  339.         argc--; mark++;
  340.         ditherType = NO_DITHER;
  341.       } else if (strcmp(argv[mark], "ppm") == 0) {
  342.         argc--; mark++;
  343.         ditherType = PPM_DITHER;
  344.       } else if (strcmp(argv[mark], "ordered") == 0) {
  345.         argc--; mark++;
  346.         ditherType = ORDERED_DITHER;
  347.       } else if (strcmp(argv[mark], "ordered2") == 0) {
  348.         argc--; mark++;
  349.         ditherType = ORDERED2_DITHER;
  350.       } else if (strcmp(argv[mark], "mbordered") == 0) {
  351.         argc--; mark++;
  352.         ditherType = MBORDERED_DITHER;
  353.       } else if (strcmp(argv[mark], "mono") == 0) {
  354.         argc--; mark++;
  355.         ditherType = MONO_DITHER;
  356.       } else if (strcmp(argv[mark], "threshold") == 0) {
  357.         argc--; mark++;
  358.         ditherType = MONO_THRESHOLD;
  359.       } else {
  360.         perror("Illegal dither option.");
  361.         usage(argv[0]);
  362.       }
  363.     } 
  364.     else if (strcmp(argv[mark], "-eachstat") == 0) {
  365.       argc--; mark++;
  366. #ifdef ANALYSIS
  367.       showEachFlag = 1;
  368. #else
  369.       fprintf(stderr, "To use -eachstat, recompile with -DANALYSIS in CFLAGS\n");
  370.       exit(1);
  371. #endif
  372.     }
  373.     else if (strcmp(argv[mark], "-shmem_off") == 0) {
  374.       argc--; mark++;
  375.       shmemFlag = 0;
  376.     }
  377. #ifdef QUIET
  378.     else if (strcmp(argv[mark], "-quiet") == 0) { 
  379.     }
  380.     else if (strcmp(argv[mark], "-noisy") == 0) {
  381. #else
  382.     else if (strcmp(argv[mark], "-noisy") == 0) {
  383.     }
  384.     else if (strcmp(argv[mark], "-quiet") == 0) { 
  385. #endif
  386.       argc--; mark++;
  387.       quietFlag = !quietFlag;
  388.     }
  389.     else if (strcmp(argv[mark], "-owncm") == 0) {
  390.       argc--; mark++;
  391.       owncmFlag = 1;
  392.     }
  393.     else if (strcmp(argv[mark], "-step") == 0) {
  394.       argc--; mark++;
  395.       requireKeypressFlag = 1;
  396.     }
  397.     else if (strcmp(argv[mark], "-loop") == 0) {
  398.       argc--; mark++;
  399.       loopFlag = 1;
  400.     }
  401.     else if (strcmp(argv[mark], "-no_display") == 0) {
  402.       argc--; mark++;
  403.       noDisplayFlag = 1;
  404.       shmemFlag=0;
  405.     }
  406.     else if (strcmp(argv[mark], "-l_range") == 0) {
  407.       argc--; mark++;
  408.       LUM_RANGE = atoi(argv[mark]);
  409.       if (LUM_RANGE < 1) {
  410.         fprintf(stderr, "Illegal luminance range value: %d\n", LUM_RANGE);
  411.         exit(1);
  412.       }
  413.       argc--; mark++;
  414.     }
  415.     else if (strcmp(argv[mark], "-cr_range") == 0) {
  416.       argc--; mark++;
  417.       CR_RANGE = atoi(argv[mark]);
  418.       if (CR_RANGE < 1) {
  419.         fprintf(stderr, "Illegal cr range value: %d\n", CR_RANGE);
  420.         exit(1);
  421.       }
  422.       argc--; mark++;
  423.     }
  424.     else if (strcmp(argv[mark], "-cb_range") == 0) {
  425.       argc--; mark++;
  426.       CB_RANGE = atoi(argv[mark]);
  427.       if (CB_RANGE < 1) {
  428.         fprintf(stderr, "Illegal cb range value: %d\n", CB_RANGE);
  429.         exit(1);
  430.       }
  431.       argc--; mark++;
  432.     } 
  433.     else if ((strcmp(argv[mark], "-?") == 0) ||
  434.                (strcmp(argv[mark], "-Help") == 0) ||
  435.                (strcmp(argv[mark], "-help") == 0)) {
  436.       usage(argv[0]);
  437.     }
  438.     else if (argv[mark][0] == '-') {
  439.       fprintf(stderr, "Un-recognized flag %s\n",argv[mark]);
  440.       usage(argv[0]);
  441.     }
  442.     else {
  443.       input = fopen(argv[mark], "r");
  444.       if (input == NULL) {
  445.         fprintf(stderr, "Could not open file %s\n", argv[mark]);
  446.         usage(argv[0]);
  447.       }
  448.       inputName = argv[mark];
  449.       argc--; mark++;
  450.     }
  451.   }
  452.  
  453.   lum_values = (int *) malloc(LUM_RANGE*sizeof(int));
  454.   cr_values = (int *) malloc(CR_RANGE*sizeof(int));
  455.   cb_values = (int *) malloc(CB_RANGE*sizeof(int));
  456.  
  457.   signal(SIGINT, int_handler);
  458.  
  459.   if ((startFrame != -1) && (endFrame != -1) &&
  460.       (endFrame < startFrame)) {
  461.     usage(argv[0]);
  462.   }
  463.  
  464.   init_tables();
  465.  
  466.   if (ditherType == MONO_DITHER || ditherType == MONO_THRESHOLD)
  467.     matched_depth = 1;
  468.  
  469.   switch (ditherType) {
  470.     
  471.   case HYBRID_DITHER:
  472.     InitColor();
  473.     InitHybridDither();
  474.     InitDisplay(name);
  475.     break;
  476.     
  477.   case HYBRID2_DITHER:
  478.     InitColor();
  479.     InitHybridErrorDither();
  480.     InitDisplay(name);
  481.     break;
  482.     
  483.   case FS4_DITHER:
  484.     InitColor();
  485.     InitFS4Dither();
  486.       InitDisplay(name);
  487.     break;
  488.     
  489.   case FS2_DITHER:
  490.     InitColor();
  491.     InitFS2Dither();
  492.     InitDisplay(name);
  493.     break;
  494.     
  495.   case FS2FAST_DITHER:
  496.     InitColor();
  497.     InitFS2FastDither();
  498.     InitDisplay(name);
  499.     break;
  500.     
  501.   case Twox2_DITHER:
  502.     InitColor();
  503.     Init2x2Dither();
  504.     InitDisplay(name);
  505.     PostInit2x2Dither();
  506.     break;
  507.  
  508.   case GRAY_DITHER:
  509.   case GRAY2_DITHER:
  510.     InitGrayDisplay(name);
  511.     break;
  512.  
  513.   case GRAY256_DITHER:
  514.   case GRAY2562_DITHER:
  515.     InitGray256Display(name);
  516.     break;
  517.  
  518.   case FULL_COLOR_DITHER:
  519.   case FULL_COLOR2_DITHER:
  520.     InitColorDisplay(name);
  521.     InitColorDither(matched_depth == 32);
  522.     break;
  523.  
  524.   case NO_DITHER:
  525.     shmemFlag = 0;
  526.     break;
  527.  
  528.   case PPM_DITHER:
  529.     shmemFlag = 0;
  530.     wpixel[0] = 0xff;
  531.     wpixel[1] = 0xff00;
  532.     wpixel[2] = 0xff0000;
  533.     matched_depth = 24;
  534.     InitColorDither(1);
  535.     break;
  536.  
  537.   case ORDERED_DITHER:
  538.     InitColor();
  539.     InitOrderedDither();
  540.     InitDisplay(name);
  541.     break;
  542.  
  543.   case MONO_DITHER:
  544.   case MONO_THRESHOLD:
  545.     InitMonoDisplay(name);
  546.     break;
  547.  
  548.   case ORDERED2_DITHER:
  549.     InitColor();
  550.     InitDisplay(name);
  551.     InitOrdered2Dither();
  552.     break;
  553.  
  554.   case MBORDERED_DITHER:
  555.     InitColor();
  556.     InitDisplay(name);
  557.     InitMBOrderedDither();
  558.     break;
  559.  
  560.   }
  561.  
  562. #ifdef SH_MEM
  563.     if (shmemFlag && (display != NULL)) {
  564.       if (!XShmQueryExtension(display)) {
  565.         shmemFlag = 0;
  566.         if (!quietFlag) {
  567.           fprintf(stderr, "Shared memory not supported\n");
  568.           fprintf(stderr, "Reverting to normal Xlib.\n");
  569.         }
  570.       }
  571.     }
  572. #endif
  573.  
  574.   if (setjmp(env) != 0) {
  575.  
  576.     DestroyVidStream(theStream);
  577.  
  578.     rewind(input);
  579.     if (seekValue < 0) seekValue = 0 - seekValue;
  580.     EOF_flag = 0;
  581.     curBits = 0;
  582.     bitOffset = 0;
  583.     bufLength = 0;
  584.     bitBuffer = NULL;
  585.     totNumFrames = 0;
  586. #ifdef ANALYSIS 
  587.     init_stats();
  588. #endif
  589.  
  590.   }
  591.  
  592.   theStream = NewVidStream((unsigned int) BUF_LENGTH);
  593.  
  594.  
  595.   mpegVidRsrc(0, theStream);
  596.  
  597.   if (IS_2x2_DITHER(ditherType)) i = 2;
  598.   else i = 1;  
  599.  
  600.   if (!noDisplayFlag) ResizeDisplay((unsigned int) curVidStream->h_size*i, 
  601.                                     (unsigned int) curVidStream->v_size*i);
  602.  
  603.   realTimeStart = ReadSysClock();
  604.  
  605.   while (1) mpegVidRsrc(0, theStream);
  606. }
  607.  
  608.  
  609. /*
  610.  *--------------------------------------------------------------
  611.  *
  612.  * usage --
  613.  *
  614.  *        Print mpeg_play usage
  615.  *
  616.  * Results:
  617.  *        None.
  618.  *
  619.  * Side effects:
  620.  *        exits with a return value -1
  621.  *
  622.  *--------------------------------------------------------------
  623.  */
  624.  
  625. void
  626. usage(s)
  627. char *s;        /* program name */
  628. {
  629.     fprintf(stderr, "Usage:\n");
  630.     fprintf(stderr, "mpeg_play [options] [filename]\n");
  631.     fprintf(stderr, "Options :\n");
  632.     fprintf(stderr, "      [-display X_display]\n");
  633.     fprintf(stderr, "      [-no_display]\n");
  634.     fprintf(stderr, "      [-dither {ordered|ordered2|mbordered|fs4|fs2|fs2fast|hybrid|\n");
  635.     fprintf(stderr, "                hybrid2|2x2|gray|gray256|color|color2|none|mono|threshold|ppm|\n");
  636.     fprintf(stderr, "                gray2|gray256x2}]\n");
  637.     fprintf(stderr, "      [-loop]\n");
  638.     fprintf(stderr, "      [-start frame_num]\n");
  639.     fprintf(stderr, "      [-end frame_num]\n");
  640.     fprintf(stderr, "      [-seek file_offset]\n");
  641.     fprintf(stderr, "      [-gamma gamma_correction_value]\n");
  642.     fprintf(stderr, "      [-framerate num_frames_per_sec]  (0 means as fast as possible)\n");
  643. #ifdef QUIET
  644.     fprintf(stderr, "      [-noisy] (turns on all program output)\n");
  645. #else
  646.     fprintf(stderr, "      [-quiet] (turns off all program output)\n");
  647. #endif
  648.     fprintf(stderr, "      [-quality {on|off}] (current default set to ");
  649. #ifdef QUALITY
  650.     fprintf(stderr, "ON)\n");
  651. #else
  652.     fprintf(stderr, "OFF)\n");
  653. #endif
  654.     fprintf(stderr, "      [-?] [-help] for help\n");
  655.     fprintf(stderr, "Rare options:\n");
  656.     fprintf(stderr, "      [-eachstat]\n");
  657.     fprintf(stderr, "      [-owncm]\n");
  658.     fprintf(stderr, "      [-shmem_off]\n");
  659.     fprintf(stderr, "      [-l_range num]\n");
  660.     fprintf(stderr, "      [-cr_range num]     [-cb_range num]\n");
  661.     fprintf(stderr, "      [-nob]              [-nop]\n");
  662. #ifdef DCPREC
  663.     fprintf(stderr, "      [-dc {8|9|10|11}] (defaults to 8)\n");
  664. #endif
  665.     exit (-1);
  666. }
  667.  
  668.  
  669.  
  670. /*
  671.  *--------------------------------------------------------------
  672.  *
  673.  * DoDitherImage --
  674.  *
  675.  *      Called when image needs to be dithered. Selects correct
  676.  *      dither routine based on info in ditherType.
  677.  *
  678.  * Results:
  679.  *        None.
  680.  *
  681.  * Side effects:
  682.  *        None.
  683.  *
  684.  *--------------------------------------------------------------
  685.  */
  686.  
  687. void
  688. DoDitherImage(l, Cr, Cb, disp, h, w) 
  689. unsigned char *l, *Cr, *Cb, *disp;
  690. int h, w;
  691. {
  692.  
  693.   switch(ditherType) {
  694.   case HYBRID_DITHER:
  695.     HybridDitherImage(l, Cr, Cb, disp, h, w);
  696.     break;
  697.  
  698.   case HYBRID2_DITHER:
  699.     HybridErrorDitherImage(l, Cr, Cb, disp, h, w);
  700.     break;
  701.  
  702.   case FS2FAST_DITHER:
  703.     FS2FastDitherImage(l, Cr, Cb, disp, h, w);
  704.     break;
  705.  
  706.   case FS2_DITHER:
  707.     FS2DitherImage(l, Cr, Cb, disp, h, w);
  708.     break;
  709.  
  710.   case FS4_DITHER:
  711.     FS4DitherImage(l, Cr, Cb, disp, h, w);
  712.     break;
  713.  
  714.   case Twox2_DITHER:
  715.     Twox2DitherImage(l, Cr, Cb, disp, h, w);
  716.     break;
  717.  
  718.   case FULL_COLOR2_DITHER:
  719.     if (matched_depth == 32)
  720.       Twox2Color32DitherImage(l, Cr, Cb, disp, h, w);
  721.     else
  722.       Twox2Color16DitherImage(l, Cr, Cb, disp, h, w);
  723.     break;
  724.  
  725.   case FULL_COLOR_DITHER:
  726.     if (matched_depth == 32)
  727.       Color32DitherImage(l, Cr, Cb, disp, h, w);
  728.     else
  729.       Color16DitherImage(l, Cr, Cb, disp, h, w);
  730.     break;
  731.  
  732.   case GRAY_DITHER:
  733.   case GRAY256_DITHER:
  734.     if (matched_depth == 8) 
  735.       GrayDitherImage(l, Cr, Cb, disp, h, w);
  736.     else if (matched_depth == 16) 
  737.       Gray16DitherImage(l, Cr, Cb, disp, h, w);
  738.     else if (matched_depth == 32 || matched_depth == 24)
  739.       Gray32DitherImage(l, Cr, Cb, disp, h, w);
  740.     break;
  741.  
  742.   case GRAY2_DITHER:
  743.   case GRAY2562_DITHER:
  744.     if (matched_depth == 8) 
  745.       Gray2DitherImage(l, Cr, Cb, disp, h, w);
  746.     else if (matched_depth == 16) 
  747.       Gray216DitherImage(l, Cr, Cb, disp, h, w);
  748.     else if (matched_depth == 32 || matched_depth == 24)
  749.       Gray232DitherImage(l, Cr, Cb, disp, h, w);
  750.     break;
  751.  
  752.   case NO_DITHER:
  753.     break;
  754.  
  755.   case PPM_DITHER:
  756.     Color32DitherImage(l, Cr, Cb, disp, h, w);
  757.     break;
  758.  
  759.   case ORDERED_DITHER:
  760.     OrderedDitherImage(l, Cr, Cb, disp, h, w);
  761.     break;
  762.  
  763.   case MONO_DITHER:
  764.     MonoDitherImage(l, Cr, Cb, disp, h, w);
  765.     break;
  766.  
  767.   case MONO_THRESHOLD:
  768.     MonoThresholdImage(l, Cr, Cb, disp, h, w);
  769.     break;
  770.  
  771.   case ORDERED2_DITHER:
  772.     Ordered2DitherImage(l, Cr, Cb, disp, h, w);
  773.     break;
  774.  
  775.   case MBORDERED_DITHER:
  776.     MBOrderedDitherImage(l, Cr, Cb, disp, h, w);
  777.     break;
  778.   }
  779. }
  780.